package com.bds.btcdc.web.service;

import com.bds.btcdc.api.model.AccountInfo;
import com.bds.btcdc.api.model.AccountInfoDto;
import com.bds.btcdc.api.model.Asset;
import com.bds.btcdc.web.model.TPairConverter;
import com.bds.btcdc.web.utils.Const;
import org.nutz.dao.Cnd;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by DongChenchen on 2018/5/16 0016
 */
@Service
public class AccountInfoService extends BaseService<AccountInfo>{
    private DecimalFormat df = new DecimalFormat(Const.END_WITH_COUNT);

    @Autowired
    private PairConverterService pairConverterService;

    public AccountInfo getByUserId(Long userid){
        return dao.fetch(AccountInfo.class, Cnd.where("userId","=",userid));
    }
    /**
     * 计算汇总金额，封装model
     * @param infos
     * @param user_id
     * @return
     */
    public AccountInfoDto caculate(List<AccountInfo> infos, Long user_id){
        AccountInfoDto accountInfoDto=new AccountInfoDto();
        accountInfoDto.setUserId(user_id);
        Map<String,BigDecimal> pair_sum=new HashMap<>();//各个币种的可用总价格
        Map<String,BigDecimal> freez_pair_sum=new HashMap<>();//各个币种的冻结总价格
        Map<String,BigDecimal> pair_count=new HashMap<>();//各个币种的可用总数量
        Map<String,BigDecimal> freez_pair_count=new HashMap<>();//各个币种的冻结总数量
        if(!CollectionUtils.isEmpty(infos)){
            for(AccountInfo accountInfo:infos) {
                try {
                    //计算该币种的 总金额
                    caculateAmountSum(accountInfo,pair_sum,
                            freez_pair_sum,
                            pair_count,
                            freez_pair_count);
                }catch (Exception e){
                    e.printStackTrace();
                    continue;
                }
            }
        }
        accountInfoDto.setAccountInfos(infos);
        caculateCoinSum(accountInfoDto,pair_sum,pair_count,freez_pair_sum,freez_pair_count);
        return accountInfoDto;
    }


    /**
     * 按币种统计
     * @param accountInfoDto
     * @param pair_sum
     * @param pair_count
     * @param freez_pair_sum
     * @param freez_pair_count
     */
    private void caculateCoinSum(AccountInfoDto accountInfoDto,
                                 Map<String,BigDecimal> pair_sum,
                                 Map<String,BigDecimal> pair_count,
                                 Map<String,BigDecimal> freez_pair_sum,
                                 Map<String,BigDecimal> freez_pair_count){
        //所有交易所，所有币种 总金额
        BigDecimal allAmount=BigDecimal.ZERO;
        BigDecimal freez_AllAmount=BigDecimal.ZERO;
        //各交易所各币种 可用总金额和总数量（按币种统计）
        Map<String, Asset> assets = new HashMap<>();//String :币种
        if(!CollectionUtils.isEmpty(pair_sum.keySet())) {
            //各个币种的可用总价格  pair_sum
            //各个币种的可用总数量  pair_count
            for (Map.Entry<String, BigDecimal> coin_sum_price : pair_sum.entrySet()) {
                try {
                    String coin = coin_sum_price.getKey();
                    Asset asset = new Asset();
                    asset.setCurrency(coin);
                    asset.setCount(df.format(pair_count.get(coin).doubleValue()));
                    BigDecimal pair_sums = pair_sum.get(coin);
                    asset.setAmount(df.format(pair_sums));
                    assets.put(coin, asset);
                    allAmount = allAmount.add(pair_sums);
                }catch (Exception e){
                    e.printStackTrace();
                    continue;
                }
            }
        }
        if(!CollectionUtils.isEmpty(pair_sum.keySet())){
            //各个币种的冻结总价格  freez_pair_sum
            //各个币种的冻结总数量  freez_pair_count
            for (Map.Entry<String, BigDecimal> coin_sum_price : freez_pair_sum.entrySet()) {
                try{
                    String coin = coin_sum_price.getKey();
                    Asset asset =null;
                    if(assets.containsKey(coin)){
                        asset=assets.get(coin);
                    }else {
                        asset = new Asset();
                        asset.setCurrency(coin);
                    }
                    asset.setFreez_count(df.format(freez_pair_count.get(coin).doubleValue()));
                    BigDecimal freez = freez_pair_sum.get(coin);
                    asset.setFreez(df.format(freez.doubleValue()));
                    assets.put(coin,asset);
                    freez_AllAmount = freez_AllAmount.add(freez);
                }catch (Exception e){
                    e.printStackTrace();
                    continue;
                }
            }
        }
        if(!CollectionUtils.isEmpty(assets.keySet())) {
            List<Asset> ass=new ArrayList<>();
            assets.values().forEach(ass::add);
            accountInfoDto.setAssetAccountList(ass);
            accountInfoDto.setAmountSum(new BigDecimal(df.format(allAmount)));
            accountInfoDto.setFreezSum(new BigDecimal(df.format(freez_AllAmount)));
            TPairConverter oneByPair = pairConverterService.getOneByPair("USD/CNY");
            BigDecimal cny=oneByPair.getReal_time_val();
            if(oneByPair!=null){
                accountInfoDto.setUsdt2cny(cny);
                accountInfoDto.setAmountSumCny(new BigDecimal(df.format(allAmount.multiply(cny))));
            }
            caculateCNY(accountInfoDto,cny);
        }
    }


    /**
     * 计算该币种的 总金额
     * @param accountInfo
     * @param pair_sum
     * @param freez_pair_sum
     * @param pair_count
     * @param freez_pair_count
     */
    private void caculateAmountSum(AccountInfo accountInfo,
                                   Map<String,BigDecimal> pair_sum,
                                   Map<String,BigDecimal> freez_pair_sum,
                                   Map<String,BigDecimal> pair_count,
                                   Map<String,BigDecimal> freez_pair_count){
        if (!CollectionUtils.isEmpty(accountInfo.getAssetList())) {
            for (Asset asset : accountInfo.getAssetList()) {
                if (asset.getLast_price() != null) {
                    try {
                        BigDecimal count_sum = BigDecimal.ZERO;//可用个数
                        BigDecimal freez_count_sum = BigDecimal.ZERO;//冻结总个数
                        BigDecimal price_sum = BigDecimal.ZERO;//可用总金额
                        BigDecimal freez_price_sum = BigDecimal.ZERO;//冻结总金额
                        if (pair_count.containsKey(asset.getCurrency())) {
                            count_sum = pair_count.get(asset.getCurrency());
                        }
                        if (freez_pair_count.containsKey(asset.getCurrency())) {
                            freez_count_sum = freez_pair_count.get(asset.getCurrency());
                        }
                        if (pair_sum.containsKey(asset.getCurrency())) {
                            price_sum = pair_sum.get(asset.getCurrency());
                        }
                        if (freez_pair_sum.containsKey(asset.getCurrency())) {
                            freez_price_sum = freez_pair_sum.get(asset.getCurrency());
                        }
                        //可用总个数
                        count_sum = count_sum.add(new BigDecimal(asset.getCount()));
                        pair_count.put(asset.getCurrency(), count_sum);
                        //冻结总个数
                        freez_count_sum = freez_count_sum.add(new BigDecimal(asset.getFreez_count()));
                        freez_pair_count.put(asset.getCurrency(), freez_count_sum);
                        //可用总金额
                        BigDecimal amounts = new BigDecimal(asset.getLast_price()).multiply(new BigDecimal(asset.getCount()));
                        price_sum = price_sum.add(amounts);
                        pair_sum.put(asset.getCurrency(), price_sum);
                        //冻结总金额
                        BigDecimal freez_amounts = new BigDecimal(asset.getLast_price()).multiply(new BigDecimal(asset.getFreez_count()));
                        freez_price_sum = freez_price_sum.add(freez_amounts);
                        freez_pair_sum.put(asset.getCurrency(), freez_price_sum);
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.info("未计算出" + asset.getCurrency() + "的总金额");
                    }
                } else {
                    logger.info("未获取到" + accountInfo.getExchange() + "-" + asset.getCurrency() + "的最新交易金额！");
                }
            }
        }
    }

    /**
     * 设置人民币
     * @param accountInfoDto
     * @param cny
     */
    private void caculateCNY(AccountInfoDto accountInfoDto,BigDecimal cny){
        //设置人民币（保证汇率统一，在此多遍历一次）
        List<AccountInfo> infos = accountInfoDto.getAccountInfos();
        for(AccountInfo info:infos){
            List<Asset> assets2 = info.getAssetList();
            for(Asset asset:assets2){
                try {
                    asset.setAmount_cny(df.format(new BigDecimal(asset.getAmount()).multiply(cny)));
                }catch (Exception e){
                    continue;
                }
            }
        }
        accountInfoDto.setAccountInfos(infos);
        List<Asset> assets = accountInfoDto.getAssetAccountList();
        for(Asset asset:assets){
            try {
                asset.setAmount_cny(df.format(new BigDecimal(asset.getAmount()).multiply(cny)));
            }catch (Exception e){
                continue;
            }
        }
        accountInfoDto.setAssetAccountList(assets);
    }



}
